package com.stormkai.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.stormkai.dao.OrderDao;
import com.stormkai.dao.SequenceInfoDao;
import com.stormkai.entity.OrderInfo;
import com.stormkai.entity.SequenceInfo;
import com.stormkai.error.BusinessException;
import com.stormkai.error.EnumBusinessError;
import com.stormkai.service.ItemService;
import com.stormkai.service.OrderService;
import com.stormkai.service.UserService;
import com.stormkai.service.model.ItemModel;
import com.stormkai.service.model.OrderModel;
import com.stormkai.service.model.UserModel;
@Service
public class OrderServiceImpl implements OrderService {
	
	@Autowired
	private ItemService itemService;
	
	@Autowired
	private UserService userService;
	
	@Autowired
	private OrderDao orderDao;
	
	@Autowired
	private SequenceInfoDao sequenceInfoDao;

	@Override
	@Transactional
	public OrderModel createOrder(Integer userId, Integer itemId, Integer promoId, Integer amount) throws BusinessException {
		// 1.校验下单状态，下单的商品是否存在，用户是否合法，购买数量是否正确
		ItemModel itemModel = itemService.getItemById(itemId);
		
		if(itemModel == null) {
			throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR,"商品信息不全");
		}
		
		UserModel userModel = userService.getUserById(userId);
		
		if(userModel == null) {
			throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR,"用户信息不存在");
		}
		
		if(amount <= 0 || amount >99) {
			throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR,"数量信息不正确");
		}
		
		//校验活动信息
		if(promoId != null) {
			// (1)校验对应活动是否存在这个使用商品
			if(promoId.intValue() != itemModel.getPromoModel().getId()) {
				throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR,"活动信息不正确");
				//(2)校验活动是否正在进行中
			}else if(itemModel.getPromoModel().getStatus() != 2) {
				throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR,"活动还未开始");
			}
			
		}
		
		// 2.落单减库存，支付减库存
		boolean result = itemService.decreaseStock(itemId, amount);
		if(!result) {
			throw new BusinessException(EnumBusinessError.STOCK_NOT_ENOUGH);
		}
		
		
		// 3.订单入库
		OrderModel orderModel = new OrderModel();
		orderModel.setUserId(userId);
		orderModel.setItemId(itemId);
		orderModel.setAmount(amount);
		if(promoId != null) {
			orderModel.setItemPrice(itemModel.getPromoModel().getPromoItemPrice());
		}else {
			orderModel.setItemPrice(itemModel.getPrice());
		}
		
		orderModel.setPromoId(promoId);
		orderModel.setOrderPrice(orderModel.getItemPrice().multiply(new BigDecimal(amount)));
		
		//生成交易流水号，订单号
		orderModel.setId(generateOrderNo());
		OrderInfo orderInfo = convertFromOrderModel(orderModel);
		orderDao.insertOrderInfo(orderInfo);
		
		//加上商品的销量
		itemService.increaseSales(itemId, amount);
		
		// 4.返回前端
		return orderModel;
	}
	
	@Transactional(propagation = Propagation.REQUIRES_NEW)//开启新事务
	private String generateOrderNo() {
		//订单号有16位
		StringBuilder sb = new StringBuilder();
		//前8位为时间信息，年月日
		LocalDateTime now = LocalDateTime.now();
		String nowDate = now.format(DateTimeFormatter.ISO_DATE).replaceAll("-", "");
		sb.append(nowDate);
		
		//中间6位为自增序列
		//获取当前sequence
		int sequence = 0;
		SequenceInfo sequenceInfo = sequenceInfoDao.querySequenceInfoByName("order_info");
		sequence = sequenceInfo.getCurrentValue();
		sequenceInfo.setCurrentValue(sequenceInfo.getCurrentValue() + sequenceInfo.getStep());
		sequenceInfoDao.updateSequenceInfo(sequenceInfo);
		
		String sequenceStr = String.valueOf(sequence);
		for(int i=0; i<6-sequenceStr.length(); i++) {
			sb.append(0);
		}
		sb.append(sequenceStr);
		
		//最后2位为分库分表位(00-99)
		/*Integer userId = 1000122;
		userId % 100*/
		sb.append("00");
		
		return sb.toString();
	}
	
	private OrderInfo convertFromOrderModel(OrderModel orderModel) {
		if(orderModel == null) {
			return null;
		}
		OrderInfo orderInfo = new OrderInfo();
		BeanUtils.copyProperties(orderModel, orderInfo);
		return orderInfo;
	}

}
